package LeetCode.题库.中等;

import org.junit.Test;
import 题组.Solution;

/**
 * @author 挚爱之夕
 * @date 2022-03-09 - 03 - 09 - 12:13
 * @Description 将一个给定字符串 s 根据给定的行数 numRows ，以从上往下、从左到右进行Z 字形排列
 * 比如输入字符串为 "PAYPALISHIRING"行数为 3 时，排列如下：
 * P   A   H   N
 * A P L S I I G
 * Y   I   R
 * 之后，你的输出需要从左往右逐行读取，产生出一个新的字符串，"PAHNAPLSIIGYIR"。
 * @Version 中等
 */
public class _6Z字形变换 {
    static String s = "PAYPALISHIRING";
    static int numRows = 3;
    @Test
    public void solve(){
        String res = convert1(_6Z字形变换.s, numRows);
        System.out.println(res);
    }
    /*by me 找规律*/
    public String convert(String s, int numRows) {
        //考虑行数为1的情况
        if(numRows == 1)
            return s;
        StringBuilder sb = new StringBuilder();
        //第一行和最后一行，两个相邻元素的索引差
        int interval = 2 * numRows - 2;
        //中间的有两个间隔（一个周期），相加等于interval
        int interval1;
        int p;
        //每行起始索引
        for(int i = 0; i < numRows; i++){
            //第一行和最后一行，相邻索引相差 2 * numRows - 2
            p = i;
            if(i == 0 || i == numRows - 1){
                while(p < s.length()){
                    sb.append(s.charAt(p));
                    p += interval;
                }
            }else{  //其他行
                while(p < s.length()){
                    sb.append(s.charAt(p));
                    interval1 = 2 *(numRows - i) - 2;
                    if(p + interval1 < s.length()){
                        sb.append(s.charAt(p + interval1));
                    }
                    //到下一个周期
                    p += interval;
                }
            }

        }
        return sb.toString();
    }
    /*官方思路*/
    //1.利用二维矩阵模拟
    public String convert1(String s, int numRows) {
        int n = s.length(), r = numRows;
        if (r == 1 || r >= n) {
            return s;
        }
        //一个周期
        int t = r * 2 - 2;
        //每行最多的元素个数
        int c = (n + t - 1) / t * (r - 1);
        char[][] mat = new char[r][c];
        for (int i = 0, x = 0, y = 0; i < n; ++i) {
            mat[x][y] = s.charAt(i);
            if (i % t < r - 1) {
                ++x; // 向下移动
            } else {
                --x;
                ++y; // 向右上移动
            }
        }
        StringBuffer ans = new StringBuffer();
        for (char[] row : mat) {
            for (char ch : row) {
                if (ch != 0) {
                    ans.append(ch);
                }
            }
        }
        return ans.toString();
    }

}
